package com.masq.aboard.service.impl;

import cn.hutool.crypto.asymmetric.RSA;
import com.masq.aboard.dao.KeyStoreRepository;
import com.masq.aboard.entity.KeyStoreEntity;
import com.masq.aboard.service.RsaKeyService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;

/**
 * RSA密钥服务实现类，提供公钥和私钥的获取服务。
 *
 * @author masq
 * @since 2024-05-03
 */
@Service
public class RsaKeyServiceImpl implements RsaKeyService {

    // 注入KeyStoreRepository，用于操作密钥仓库
    private final KeyStoreRepository keyStoreRepository;

    @Autowired
    public RsaKeyServiceImpl(KeyStoreRepository keyStoreRepository) {
        this.keyStoreRepository = keyStoreRepository;
    }

    /**
     * 获取指定别名的公钥。
     * 如果数据库中不存在该别名的公钥，则生成新的公钥对并保存至数据库。
     *
     * @param keyAlias 密钥别名，用于标识特定的公钥和私钥。
     * @return 返回Base64编码后的公钥字符串。
     */
    @Override
    public String getPublicKey(String keyAlias) {
        // 查询数据库中是否存在对应别名的启用状态的公钥
        KeyStoreEntity keyStoreEntity = keyStoreRepository.findKeyStoreEntitiesByKeyAliasAndEnabledTrue(keyAlias);
        if (keyStoreEntity == null) {
            // 生成新的密钥对并保存至数据库
            keyStoreEntity = generateKeyPair(keyAlias);
        }
        return keyStoreEntity.getPublicKey();
    }

    /**
     * 获取指定别名的私钥。
     * 如果数据库中不存在该别名的私钥，则生成新的公钥对并保存至数据库。
     *
     * @param keyAlias 密钥别名，用于标识特定的公钥和私钥。
     * @return 返回Base64编码后的私钥字符串。
     */
    @Override
    public String getPrivateKey(String keyAlias) {
        // 查询数据库中是否存在对应别名的启用状态的私钥
        KeyStoreEntity keyStoreEntity = keyStoreRepository.findKeyStoreEntitiesByKeyAliasAndEnabledTrue(keyAlias);
        if (keyStoreEntity == null) {
            // 生成新的密钥对并保存至数据库
            keyStoreEntity = generateKeyPair(keyAlias);
        }
        return keyStoreEntity.getPrivateKey();
    }

    @Override
    public RSA getRsaByAlias(String keyAlias) {
        KeyStoreEntity keyStoreEntity = keyStoreRepository.findKeyStoreEntitiesByKeyAliasAndEnabledTrue(keyAlias);
        if (keyStoreEntity == null) {
            // 生成新的密钥对并保存至数据库
            keyStoreEntity = generateKeyPair(keyAlias);
        }
        return new RSA(keyStoreEntity.getPrivateKey(), keyStoreEntity.getPublicKey());
    }

    /**
     * 生成RSA密钥对，并保存至数据库。
     *
     * @param keyAlias 密钥别名，用于标识生成的密钥对。
     * @return 保存至数据库后的KeyStoreEntity对象。
     */
    private KeyStoreEntity generateKeyPair(String keyAlias) {
        KeyStoreEntity keyStoreEntity = new KeyStoreEntity();
        keyStoreEntity.setKeyAlias(keyAlias);
        keyStoreEntity.setEnabled(true);
        keyStoreEntity.setCreateTime(new Date());
        keyStoreEntity.setExpireTime(-1L);
        // 尝试生成RSA密钥对
        RSA rsa = new RSA();
        // 设置公钥和私钥信息
        keyStoreEntity.setPublicKey(rsa.getPublicKeyBase64());
        keyStoreEntity.setPrivateKey(rsa.getPrivateKeyBase64());
        return keyStoreRepository.save(keyStoreEntity);
    }
}
